﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cdhpy.Util
{
    /// <summary>
    /// Precise of timestamp
    /// </summary>
    public enum TimestampPrecise
    {
        ToSeconds = 0,
        ToMilliseconds = 1
    }

    /// <summary>
    /// Produce timestamp 
    /// </summary>
    public sealed class Timestamp
    {
        /// <summary>
        /// Get timestamp at the moment
        /// </summary>
        /// <returns>timestamp precisely to seconds</returns>
        public static long Get()
        {
            return Get(DateTime.Now);

            //OR
            //TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            //return (long)ts.TotalSeconds;

            //OR
            //return (TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1))).TotalSeconds
        }

        /// <summary>
        /// Get timestamp at the moment
        /// </summary>
        /// <param name="precise">timestamp precise</param>
        /// <returns>timestamp</returns>
        public static long Get(TimestampPrecise precise)
        {
            return Get(DateTime.Now, precise);
        }

        /// <summary>
        /// Get timestamp of a specific time
        /// </summary>
        /// <param name="time">the specified datetime</param>
        /// <returns>timestamp precisely to seconds</returns>
        public static long Get(DateTime time)
        {
            return (time.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
        }

        /// <summary>
        /// Get timestamp of a specific time
        /// </summary>
        /// <param name="time">the specified datetime</param>
        /// <param name="precise">timestamp precise</param>
        /// <returns></returns>
        public static long Get(DateTime time, TimestampPrecise precise)
        {
            if (precise == TimestampPrecise.ToSeconds)
                return (time.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
            else
                return (time.ToUniversalTime().Ticks - 621355968000000000) / 10000;
        }

        /// <summary>
        /// Parse timestamp to DateTime
        /// </summary>
        /// <param name="timestamp">(can be precisely to seconds or milliseconds)</param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <returns></returns>
        public static DateTime Parse(long timestamp)
        {
            try
            {
                System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);

                if (timestamp.ToString().Length == 10)
                    return dtDateTime.AddSeconds(timestamp).ToLocalTime();
                else
                    return dtDateTime.AddMilliseconds(timestamp).ToLocalTime();
            }
            catch
            {
                throw;
            }
        }

        /// <summary>
        /// Get timestamp at the moment
        /// </summary>
        /// <returns></returns>
        [Obsolete]
        public static long GetNow()
        {
            return Get(DateTime.Now);
        }
    }
}
